<template>
  <li :class="{ completed: todo.done, editing: editing }" class="todo">
    <div class="view">
      <input :checked="todo.done" class="toggle" type="checkbox" @change="toggleTodo(todo)">
      <label @dblclick="editing = true" v-text="todo.text" />
      <button class="destroy" @click="deleteTodo(todo)" >&times;</button>
    </div>

    <input v-show="editing" v-focus="editing" :value="todo.text" class="edit" @keyup.enter="doneEdit"
      @keyup.esc="cancelEdit" @blur="doneEdit">
  </li>
</template>

<script setup lang="ts">
import { defineProps, ref } from 'vue'

export interface TodoItem {
  text: string
  done: boolean
}

const vFocus = {
  mounted (el: HTMLInputElement) {
    el.focus()
  },
}

const editing = ref(false)

const props = withDefaults(defineProps<{ todo: TodoItem }>(), {
  todo: (): TodoItem => ({
    text: '',
    done: false
  })
})
const emit = defineEmits<{
  (name: 'delete-todo', todo: TodoItem): void
  (name: 'edit-todo', { todo, value }: { todo: TodoItem, value: string }): void
  (name: 'toggle-todo', todo: TodoItem): void
}>()

const deleteTodo = (todo: TodoItem) => {
  emit('delete-todo', todo)
}

const editTodo = ({ todo, value }: { todo: TodoItem, value: string }) => {
  emit('edit-todo', { todo, value })
}

const toggleTodo = (todo: TodoItem) => {
  emit('toggle-todo', todo)
}

const cancelEdit = (e: KeyboardEvent) => {
  (e.target as HTMLInputElement).value = props.todo.text
  editing.value = false
}

const doneEdit = (e: FocusEvent) => {
  const value = (e.target as HTMLInputElement).value.trim()
  const todo = props.todo
  if (!value) {
    deleteTodo(todo)
  } else if (editing.value) {
    editTodo({
      todo,
      value
    })
    editing.value = false
  }
}
</script>

<style lang="scss" scoped>
.todo {
  padding: 0 20px;

  .view {
    height: 40px;
    line-height: 1;
    display: flex;
    align-items: center;

    .toggle {
      margin-right: 10px;
    }

    label {
      flex: 1;
      font-size: 14px;
      font-weight: 400;
    }

    .destroy {
      float: right;
      padding: 2px 3px;
      line-height: 1;
      font-size: 18px;
      border: 0;
      background: transparent;
      margin-top: 23x;
    }
  }
}
</style>
